/*
 * Main.c
 *
 *  Created on: Feb 7, 2010
 *      Author: diqiu
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>

#include "include.h"
#include "SerialIO.h"
/*
 * Fork a child process.
 * Parent process should catch QUIT command, and send SIGTERM to child process
 * Child process should catch SIGTERM and return
 * Parent process should not quit on ctrl+C
 */

void sigintHandler();

int main(int argc, char** argv) {
    pid_t pid;
    int childReturnValue;
    char cliInput[256];	// Command line input to main process
    memset(&cliInput, 0, sizeof(char)*256);	// Clear cliInput variable

    // Create a data pipe to talk to serial IO process
    int serialIOPipe[2];
    if (pipe(serialIOPipe)==-1) {
    	perror("FATAL: pipe() failed.");
    	exit(1);
    }

    // Setup SIGINT handler to disable ctrl+c and prevent zombie child
    struct sigaction newAction;
    newAction.sa_handler = sigintHandler;
    sigemptyset(&newAction.sa_mask);
    newAction.sa_flags = 0;
    if ( sigaction (SIGINT, &newAction, NULL) == -1 ) {
    	perror("FATAL: signal() failed.");
    	exit(1);
    }

    switch(pid = fork()) {
    case -1:
        perror("FATAL: fork() failed.");
        exit(1);
    case 0:		// Child process to handle serial IO
    	// Pass commandPipe to child
        childReturnValue = serialIOMain((void *)&serialIOPipe);
        exit(childReturnValue);
    default:	// Parent process
    	// Close child end of pipe
    	close(serialIOPipe[1]);

		#if DEBUG == 1
    	printf("DEBUG: Serial IO's PID is: %d\n", pid);
		#endif

        while (1) {
        	// TODO: Parent process should sends SIGUSR1 to child. Packet is expect to be read from data pipe.
        	// TODO: Parent process should utilize the data sent by client to drive uinput.
			scanf("%s", cliInput);
			if (strcmp(cliInput, "QUIT")==0) {
				#if DEBUG == 1
				printf("DEUBG: Sending SIGTERM to child.\n");
				#endif

				// Send SIGTERM to tell serialIO child to exit
				if ( kill(pid, SIGTERM) == -1) {
					perror("FATAL: kill() failed.");
				}
				wait(&childReturnValue);
				break;
			}
        }
    }

	return 0;
}

void sigintHandler() {
	printf("Type QUIT to exit.\n");
}
